package com.cloud.screen.api.service.impl;

import com.cloud.screen.api.service.ForceService;
import com.cloud.screen.api.service.LawCaseService;
import com.cloud.screen.api.service.PunishService;
import com.cloud.screen.interfaces.FeignClientLawCase;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by csc on 2019/7/22.
 */
@Service
@Transactional
public class LawCaseServiceImpl implements LawCaseService {

    @Autowired
    private FeignClientLawCase feignClientLawCase;

    @Autowired
    private PunishService punishService;

    @Autowired
    private ForceService forceService;

    @Override
    public Map<String, Object> getInfoGeneral() {
        return feignClientLawCase.getInfoGeneral();
    }

    @Override
    public List<Map<String, Object>> statCauseExcuteType() {
        return feignClientLawCase.statCauseExcuteType();
    }

    @Override
    public List<Map<String, Object>> getLegalCaseGroup(String start, String end, Long regionid) {
        List<Map<String, Object>> list = new ArrayList<>();

        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getLawCaseTop(start, end, regionid, -1);
            List<Map<String, Object>> force = (List) forceService.getLawCaseTop(start, end, regionid, -1);
            listNumAdd(punish, force, "lawcode", "count");
            for (Map<String, Object> map : force) {
                if (map.get("hasAdd") == null) {
                    punish.add(map);
                }
            }

            // 获取法律法规分组
            Map<String, Map<String, Object>> codes = new HashedMap();
            Map<String, Map<String, Object>> codeGroup = new HashedMap();
            List<Map<String, Object>> groups = feignClientLawCase.getLawCodeGroup();
            for (Map<String, Object> group : groups) {
                if (group.get("lawcode") != null) {
                    codeGroup.put(group.get("lawcode").toString(), group);
                }

                String groupId = group.get("groupid").toString();
                Map<String, Object> item = codes.get(groupId);
                if (item == null) {
                    item = new HashedMap();
                    item.put("id", group.get("groupid"));
                    item.put("name", group.get("groupname"));
                    item.put("count", 0);
                }
                codes.put(groupId, item);
            }

            for (Map<String, Object> map : punish) {
                if (map.get("lawcode") != null) {
                    String lawCode = map.get("lawcode").toString();

                    Map<String, Object> group = codeGroup.get(lawCode);
                    String groupId = group.get("groupid").toString();

                    Map<String, Object> item = codes.get(groupId);
                    Long count = item.get("count") == null ? 0 : Long.parseLong(item.get("count").toString());
                    count += map.get("count") == null ? 0 : Long.parseLong(map.get("count").toString());
                    item.put("count", count);
                }
            }
            list = new ArrayList(codes.values());
        } catch (Exception ex) {
        }

        return list;
    }

    @Override
    public List<Map<String, Object>> getLegalCaseDomain(String start, String end, Long regionid) {
        List<Map<String, Object>> list = new ArrayList<>();

        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getLegalCaseDomain(start, end, regionid, -1, 10);
            List<Map<String, Object>> force = (List) forceService.getLegalCaseDomain(start, end, regionid, -1, 10);
            listNumAdd(punish, force, "timeRange", "count");
            for (Map<String, Object> map : force) {
                if (map.get("hasAdd") == null) {
                    punish.add(map);
                }
            }

            for (Map<String, Object> map : punish) {
                if (list.size() < 10) {
                    list.add(map);
                } else {
                    break;
                }
            }
            if (list.size() < 7) {
                List<Map<String, Object>> domains = feignClientLawCase.getLawDomain();
                Map<String, Integer> names = new HashMap<>();
                for (Map<String, Object> map : punish) {
                    names.put(map.get("timeRange").toString(), 1);
                }
                for (Map<String, Object> domain : domains) {
                    String name = domain.get("name").toString();
                    if (names.get(name) == null) {
                        if (list.size() < 7) {
                            Map<String, Object> map = new HashMap<>();
                            map.put("timeRange", name);
                            map.put("count", 0);

                            list.add(map);
                        } else {
                            break;
                        }
                    }
                }

            }
        } catch (Exception ex) {
        }

        return list;
    }

    @Override
    public Map<String, Object> getLegalCaseRegion(String start, String end, Long regionid) {
        Map<String, Object> res = new HashedMap();

        try {
            Map<String, Object> stat = new HashedMap();

            // 所有类型结果
            Map<String, Object> punish = (Map) punishService.getLegalCaseRegion(start, end, regionid, 0).get("stat");
            Map<String, Object> force = (Map) forceService.getLegalCaseRegion(start, end, regionid, 0).get("stat");

            // 合并 region 的 sumnum 值
            Map<String, Object> punishRegion = (Map) punish.get("region");
            Map<String, Object> forceRegion = (Map) force.get("region");
            punishRegion.put("sumnum", mapNumAdd(punishRegion, forceRegion, "sumnum"));
            stat.put("region", punishRegion);

            // 合并 children 的 sumnum 值
            List<Map<String, Object>> punishChildren = (List) punish.get("children");
            List<Map<String, Object>> forceChildren = (List) force.get("children");
            listNumAdd(punishChildren, forceChildren, "regioncode", "sumnum");
            stat.put("children", punishChildren);

            res.put("stat", stat);
        } catch (Exception ex) {
        }

        return res;
    }

    @Override
    public List<Map<String, Object>> getLegalCaseInfo(String start, String end, Long regionid, Integer type) {
        List<Map<String, Object>> list = new ArrayList<>();

        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getLegalCaseInfo(start, end, regionid, type, 0);
            List<Map<String, Object>> force = (List) forceService.getLegalCaseInfo(start, end, regionid, type, 0);

            // 所有时间
            Map<String, Integer> times = new HashedMap();
            allTimeRange(times, punish);
            allTimeRange(times, force);

            fillTimeRange(times, punish);
            fillTimeRange(times, force);

            // 组合数据
            Map<String, Object> infoPunish = new HashMap<>();
            infoPunish.put("name", "行政处罚");
            infoPunish.put("list", punish);
            list.add(infoPunish);
            Map<String, Object> infoForce = new HashMap<>();
            infoForce.put("name", "行政强制");
            infoForce.put("list", force);
            list.add(infoForce);
        } catch (Exception ex) {
        }

        return list;
    }

    @Override
    public List<Map<String, Object>> getLawCaseTop(String start, String end, Long regionid) {
        List<Map<String, Object>> list = new ArrayList<>();

        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getLawCaseTop(start, end, regionid, 10);
            List<Map<String, Object>> force = (List) forceService.getLawCaseTop(start, end, regionid, 10);
            listNumAdd(punish, force, "lawcode", "count");
            for (Map<String, Object> map : force) {
                if (map.get("hasAdd") == null) {
                    punish.add(map);
                }
            }

            // 取 10
            for (Map<String, Object> map : punish) {
                if (list.size() < 10) {
                    list.add(map);
                }
            }
        } catch (Exception ex) {
        }

        return list;
    }

    @Override
    public List<Map<String, Object>> getLawUseStat(String start, String end, Long regionid) {
        List<Map<String, Object>> list = new ArrayList<>();

        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getLawUseStat(start, end, regionid);
            List<Map<String, Object>> force = (List) forceService.getLawUseStat(start, end, regionid);
            listNumAdd(punish, force, "lawcode", "count");
            for (Map<String, Object> map : force) {
                if (map.get("hasAdd") == null) {
                    punish.add(map);
                }
            }


            for (Map<String, Object> map : punish) {
                list.add(map);
            }

            Collections.sort(list, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    Integer name1 = Integer.valueOf(o1.get("count").toString()) ;//name1是从你list里面拿出来的一个
                    Integer name2 = Integer.valueOf(o2.get("count").toString()) ; //name1是从你list里面拿出来的第二个name
                    return name2.compareTo(name1);
                }
            });

        } catch (Exception ex) {
        }

        return list;
    }

    @Override
    public List<Map<String, Object>> getCauseUseStat(String start, String end, Long regionid, String lawID) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            // 所有类型结果
            List<Map<String, Object>> punish = (List) punishService.getCauseUseStat(start, end, regionid, lawID);
            List<Map<String, Object>> force = (List) forceService.getCauseUseStat(start, end, regionid, lawID);
            listNumAdd(punish, force, "lawcode", "count");
            for (Map<String, Object> map : force) {
                if (map.get("hasAdd") == null) {
                    punish.add(map);
                }
            }


            for (Map<String, Object> map : punish) {
                list.add(map);
            }

            Collections.sort(list, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    Integer name1 = Integer.valueOf(o1.get("count").toString()) ;//name1是从你list里面拿出来的一个
                    Integer name2 = Integer.valueOf(o2.get("count").toString()) ; //name1是从你list里面拿出来的第二个name
                    return name2.compareTo(name1);
                }
            });

        } catch (Exception ex) {
        }

        return list;
    }

    private void allTimeRange(Map<String, Integer> times, List<Map<String, Object>> list) {
        if (list != null) {
            for (Map<String, Object> map : list) {
                String timeRange = map.get("timeRange") == null ? "" : map.get("timeRange").toString();
                if (times.get(timeRange) == null) {
                    times.put(timeRange, 1);
                }
            }
        }
    }

    private void fillTimeRange(Map<String, Integer> times, List<Map<String, Object>> list) {
        List<String> allTimes = new ArrayList(times.keySet());
        List<String> inTimes = new ArrayList<>();

        if (list != null) {
            list.forEach(map -> {
                inTimes.add(map.get("timeRange").toString());
            });
            inTimes.forEach(map -> {
                allTimes.removeIf(item -> item.contains(map));
            });
            allTimes.forEach(timeRange -> {
                Map<String, Object> map = new HashMap<>();
                map.put("timeRange", timeRange);
                map.put("count", 0);
                list.add(map);
            });
            list.sort(Comparator.comparing(o -> o.get("timeRange").toString()));
        }
    }

    private void listNumAdd(List<Map<String, Object>> a, List<Map<String, Object>> b, String name, String num) {
        if (a != null && b != null) {
            for (Map<String, Object> mapA : a) {
                for (int i = 0; i < b.size(); i++) {
                    Map<String, Object> mapB = b.get(i);
                    if (mapA.get(name).equals(mapB.get(name))) {
                        mapA.put(num, mapNumAdd(mapA, mapB, num));

                        mapB.put("hasAdd", 1);
                        break;
                    }
                }
            }
        }
    }

    private Integer mapNumAdd(Map<String, Object> a, Map<String, Object> b, String num) {
        Integer numA = a.get(num) == null ? 0 : Integer.parseInt(a.get(num).toString());
        Integer numB = b.get(num) == null ? 0 : Integer.parseInt(b.get(num).toString());

        return numA + numB;
    }
}
